From 6227a5a34c29cbeddf2fec9743ba27e9db38456c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Sun, 26 Aug 2018 23:18:32 +0200 Subject: [PATCH] extensions: handle negative premultiplied alpha --- extensions/double.c | 9 +++++++-- extensions/fast-float.c | 13 +++++++------ extensions/float.c | 14 ++++++++++++-- extensions/gegl-fixups.c | 22 +++++++++++++--------- extensions/gggl-table-lies.c | 2 +- extensions/sse2-float.c | 25 ++++++++++++++++++++----- extensions/two-table.c | 2 +- 7 files changed, 61 insertions(+), 26 deletions(-) diff --git a/extensions/double.c b/extensions/double.c index ec45be4..502a466 100644 --- a/extensions/double.c +++ b/extensions/double.c @@ -42,8 +42,13 @@ conv_rgbaD_linear_rgbAD_gamma (const Babl *conversion,unsigned char *src, while (n--) { double alpha = fsrc[3]; - if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; + if (alpha <= BABL_ALPHA_FLOOR) + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + } *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha; diff --git a/extensions/fast-float.c b/extensions/fast-float.c index 822bc97..5540185 100644 --- a/extensions/fast-float.c +++ b/extensions/fast-float.c @@ -310,7 +310,12 @@ conv_rgbaF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src, else { if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + } *fdst++ = linear_to_gamma_2_2_lut (red) * alpha; *fdst++ = linear_to_gamma_2_2_lut (green) * alpha; *fdst++ = linear_to_gamma_2_2_lut (blue) * alpha; @@ -451,8 +456,6 @@ conv_rgbaF_linear_rgbA8_gamma_cairo (const Babl *conversion,unsigned char *src, float green = *fsrc++; float blue = *fsrc++; float alpha = *fsrc++; - if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; if (alpha >= 1.0) { int val = linear_to_gamma_2_2_lut (blue) * 0xff + 0.5f; @@ -493,9 +496,7 @@ conv_rgbAF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src, float blue = *fsrc++; float alpha = *fsrc++; - if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; - if (alpha >= 1.0) + if (alpha == 1.0) { *fdst++ = linear_to_gamma_2_2_lut (red); *fdst++ = linear_to_gamma_2_2_lut (green); diff --git a/extensions/float.c b/extensions/float.c index 0d42586..eaa38f5 100644 --- a/extensions/float.c +++ b/extensions/float.c @@ -44,7 +44,12 @@ conv_rgbaF_linear_rgbAF_nonlinear (const Babl *conversion,unsigned char *src, { float alpha = fsrc[3]; if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + } *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha; @@ -66,7 +71,12 @@ conv_rgbaF_linear_rgbAF_perceptual (const Babl *conversion,unsigned char *src, { float alpha = fsrc[3]; if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + } *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; diff --git a/extensions/gegl-fixups.c b/extensions/gegl-fixups.c index e05126c..70ef2d3 100644 --- a/extensions/gegl-fixups.c +++ b/extensions/gegl-fixups.c @@ -331,9 +331,9 @@ conv_rgbAF_rgb8 (const Babl *conversion,unsigned char *srcc, float alpha = src[3]; if (alpha == 0.0f) { - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; + dst[0] = 0.0f; + dst[1] = 0.0f; + dst[2] = 0.0f; } else { @@ -381,7 +381,12 @@ conv_rgbaF_rgbAF (const Babl *conversion,unsigned char *srcc, { float alpha = src[3]; if (alpha < BABL_ALPHA_FLOOR) - alpha = BABL_ALPHA_FLOOR; + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + } dst[0] = src[0] * alpha; dst[1] = src[1] * alpha; dst[2] = src[2] * alpha; @@ -412,10 +417,9 @@ conv_rgbAF_rgbaF (const Babl *conversion,unsigned char *srcc, dst[0] = src[0] * recip; dst[1] = src[1] * recip; dst[2] = src[2] * recip; - if (alpha == BABL_ALPHA_FLOOR) - dst[3] = 0.0f; - else - dst[3] = alpha; + if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR) + alpha = 0.0f; + dst[3] = alpha; src += 4; dst += 4; } @@ -441,7 +445,7 @@ conv_rgbAF_lrgba8 (const Babl *conversion,unsigned char *srcc, else { float recip = (1.0/alpha); - if (alpha == BABL_ALPHA_FLOOR) + if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR) alpha = 0.0f; dst[0] = table_F_8[gggl_float_to_index16 (src[0] * recip)]; dst[1] = table_F_8[gggl_float_to_index16 (src[1] * recip)]; diff --git a/extensions/gggl-table-lies.c b/extensions/gggl-table-lies.c index 02904a6..e70a45a 100644 --- a/extensions/gggl-table-lies.c +++ b/extensions/gggl-table-lies.c @@ -316,7 +316,7 @@ conv_rgbafloat_linear_cairo32_le (const Babl *conversion,unsigned char *src_char { float alpha = src[3] * 255; - if (alpha < BABL_ALPHA_FLOOR) + if (alpha <= BABL_ALPHA_FLOOR) { *(int *)dst = 0; } diff --git a/extensions/sse2-float.c b/extensions/sse2-float.c index b00ecc0..02a8c2d 100644 --- a/extensions/sse2-float.c +++ b/extensions/sse2-float.c @@ -55,9 +55,19 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float * float alpha1 = ((float *)s)[7]; if (alpha0 < BABL_ALPHA_FLOOR) - ((float *)s)[3] = BABL_ALPHA_FLOOR; + { + if (alpha0 >= 0.0f) + ((float *)s)[3] = BABL_ALPHA_FLOOR; + else + ((float *)s)[3] = -BABL_ALPHA_FLOOR; + } if (alpha1 < BABL_ALPHA_FLOOR) - ((float *)s)[7] = BABL_ALPHA_FLOOR; + { + if (alpha1 >= 0.0f) + ((float *)s)[7] = BABL_ALPHA_FLOOR; + else + ((float *)s)[7] = -BABL_ALPHA_FLOOR; + } { __v4sf rbaa0, rbaa1; @@ -93,8 +103,13 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float * while (remainder--) { float a = src[3]; - if (a < BABL_ALPHA_FLOOR) - a = BABL_ALPHA_FLOOR; + if (a <= BABL_ALPHA_FLOOR) + { + if (a >= 0.0f) + a = BABL_ALPHA_FLOOR; + else if (a >= -BABL_ALPHA_FLOOR) + a = -BABL_ALPHA_FLOOR; + } dst[0] = src[0] * a; dst[1] = src[1] * a; dst[2] = src[2] * a; @@ -144,7 +159,7 @@ conv_rgbAF_linear_rgbaF_linear_shuffle (const Babl *conversion,const float *src, rbaa0 = _mm_shuffle_ps(rgba0, pre_rgba0, _MM_SHUFFLE(3, 3, 2, 0)); rgba0 = _mm_shuffle_ps(rgba0, rbaa0, _MM_SHUFFLE(2, 1, 1, 0)); - if (alpha0 == BABL_ALPHA_FLOOR) + if (alpha0 == BABL_ALPHA_FLOOR || alpha0 == -BABL_ALPHA_FLOOR) ((float *)d)[3] = 0.0f; s++; diff --git a/extensions/two-table.c b/extensions/two-table.c index d4f914f..dae28c8 100644 --- a/extensions/two-table.c +++ b/extensions/two-table.c @@ -89,7 +89,7 @@ conv_rgbafloat_linear_rgbu8_gamma (const Babl *conversion,unsigned char *src_cha while (n--) { - if (src[3] < BABL_ALPHA_FLOOR) + if (src[3] <= BABL_ALPHA_FLOOR) { dst[0] = 0; dst[1] = 0; -- 2.30.2